package com.kinderas.numbers{
	/**
	 * Class that handles mapping functionality 
	 * @author jorn.kinderas
	 * 
	 */	
	public class Maps{
		/**
		 * Converts from Universal Transverse Marcator (UTM) to Latitude and Longtitude
		 * 
		 * @param easting
		 * @param northing 
		 * @param zone (UTM Zone)
		 * @param northernHemisphere
		 * @return Array with latitude and longtitude values
		 * 
		 */		
		public static function UTMtoLatLong(easting:Number, northing:Number, zone:int = 32, northernHemisphere:Boolean = true):Array 
			{
				if(!northernHemisphere){
					northing = 10000000 - northing;
				}
				// GRS 80 datum
				var a:Number = 6378137; // equatorial radius
				// b = 6356752.3141 // polar radius
				// Flattening : 1/298.257222101
				var long0:Number = ((zone-1)*6)-180+3; // central meridian of zone
				var k0:Number = 0.9996; // scale along long0
				var onef:Number = 298.257223563;
				var e2:Number = 2*(1/onef)-Math.pow((1/onef),2);
				// This is the eccentricity of the earth's elliptical cross-section.
				var ex2:Number = e2/(1-e2);
				var ny:Number = northing;
				var nx:Number = easting-500000; // (relative to central meridian; subtract 500,000 from conventional UTM coordinate).
				// Calculate the Meridional Arc
				var M:Number = ny/k0;
				// Calculate Footprint Latitude (fp)
				var mu:Number = M/(a*(1 - e2/4 - 3*Math.pow(e2,2)/64 - 5*Math.pow(e2,3)/256));
				var e1:Number = (1-Math.sqrt(1-e2))/(1+Math.sqrt(1-e2));
				var J1:Number = (3*e1/2 - 27*Math.pow(e1,3)/32);
				var J2:Number = (21*Math.pow(e1,2)/16 - 55*Math.pow(e1,4)/32);
				var J3:Number = (151*Math.pow(e1,3)/96);
				var J4:Number = (1097*Math.pow(e1,4)/512);
				var fp:Number = mu + J1*Math.sin(2*mu) + J2*Math.sin(4*mu) + J3*Math.sin(6*mu) + J4*Math.sin(8*mu);
				// Calculate Latitude and Longitude
				var C1:Number = ex2*Math.pow((Math.cos(fp)),2);
				var T1:Number = Math.pow((Math.tan(fp)),2);
				var R1:Number = a*(1-e2)/Math.pow((1-e2*Math.pow((Math.sin(fp)),2)),3/2);
				var N1:Number = a/Math.pow((1-e2*Math.pow(Math.sin(fp),2)),1/2);
				var D:Number = nx/(N1*k0);
				var Q1:Number = N1*Math.tan(fp)/R1;
				var Q2:Number = (Math.pow(D,2)/2);
				var Q3:Number = (5 + (3*T1) + (10*C1) - Math.pow((4*C1),2) - 9*ex2)*Math.pow(D,4)/24;
				var Q4:Number = (61 + 90*T1 + 298*C1 + 45*Math.pow(T1,2) - 3*Math.pow(C1,2) - 252*ex2)*Math.pow(D,6)/720;
				var Q5:Number = D;
				var Q6:Number = (1 + 2*T1 + C1)*Math.pow(D,3)/6;
				var Q7:Number = (5 - 2*C1 + 28*T1 - 3*Math.pow(C1,2) + 8*ex2 + 24*Math.pow(T1,2))*Math.pow(D,5)/120;
				var lat:Number = Trig.radToDeg(fp - Q1 * (Q2 - Q3 + Q4));
				var long:Number = long0 + Trig.radToDeg((D-(1+2*T1+C1)*(Math.pow(D,3))/6 + (5-2*C1+28*T1-3*Math.pow(C1,2)+8*ex2+24*Math.pow(T1,2))*(Math.pow(D,5))/120)/Math.cos(fp));
				return ([lat,long]);
			}
	}
}